﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace 数据换算.ViewModel
{
    public enum DistanceType
    {
        METRE,
        MILLIMETRE,
        MIL,
        SI,
        INCH
    }
    public class DistanceViewModel : INotifyPropertyChanged
    {
        private string[] Types;
        private delegate double Convert(double value);
        private delegate double ConvertBack(double value);

        private Dictionary<DistanceType, Convert> Converts = new Dictionary<DistanceType, Convert>()
        {
            {DistanceType.METRE, (x)=>{return x; } },
            {DistanceType.MILLIMETRE, (x)=>{return x/1000; } },
            {DistanceType.MIL, (x)=>{return x*0.0254/1000; } },
            {DistanceType.SI, (x)=>{return x/100000; } },
            {DistanceType.INCH, (x)=>{return x*0.0254; } }
        };

        private Dictionary<DistanceType, ConvertBack> ConvertBacks = new Dictionary<DistanceType, ConvertBack>()
        {
            {DistanceType.METRE, (x)=>{return x; } },
            {DistanceType.MILLIMETRE, (x)=>{return x *1000; } },
            {DistanceType.MIL, (x)=>{return x*1000/0.0254; } },
            {DistanceType.SI, (x)=>{return x*100000; } },
            {DistanceType.INCH, (x)=>{return x/0.0254; } }
        };


        public event PropertyChangedEventHandler PropertyChanged;


        private double _Metre = 0;
        public double Metre
        {
            get => _Metre;
            set
            {
                _Metre = value;
                ValueChanged(DistanceType.METRE, value);
            }
        }

        private double _Millimetre;
        public double Millimetre
        {
            get => _Millimetre;
            set
            {
                _Millimetre = value;
                ValueChanged(DistanceType.MILLIMETRE, value);
            }
        }

        private double _Mil;
        public double Mil
        {
            get => _Mil;
            set
            {
                _Mil = value;
                ValueChanged(DistanceType.MIL, value);
            }
        }

        private double _Si;
        public double Si
        {
            get => _Si;
            set
            {
                _Si = value;
                ValueChanged(DistanceType.SI, value);
            }
        }

        private double _Inch;
        public double Inch
        {
            get => _Inch;
            set
            {
                _Inch = value;
                ValueChanged(DistanceType.INCH, value);
            }
        }


        public DistanceViewModel()
        {
            List<string> types = new List<string>();
            string[] names = Enum.GetNames(typeof(DistanceType));
            foreach(string name in names)
            {
                string type = string.Concat(name[0], name.Substring(1).ToLower());
                types.Add(type);
            }
            Types = types.ToArray();
        }

        public void ValueChanged(DistanceType type, double value)
        {
            double metricValue = 0;
            metricValue = Converts[type](value);

            foreach(string t in Types)
            {
                if (!t.ToUpper().Equals(type.ToString()))
                {
                    string propName = string.Concat('_', t);
                    DistanceType dt;
                    Enum.TryParse(t.ToUpper(), out dt);
                    Type type1 = this.GetType();
                    FieldInfo field = type1.GetField(propName, BindingFlags.NonPublic | BindingFlags.Instance);
                    field.SetValue(this, ConvertBacks[dt](metricValue));
                }
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(t));
            }
        }
    }
}
